package com.example.function.integration.controller;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.example.function.integration.dto.ImageFileDownloadAndUploadReqDto;
import com.example.function.integration.service.ImageFileDownloadService;
import com.example.function.integration.sftp.CommonSftpComponent;
import com.example.function.integration.utils.SftpUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:华能影像件下载并导出
 * @className:ImageFileDownloadController
 * @author:ext.fengcheng
 * @date:2023/9/20 10:14
 */
@RestController
@RequestMapping("/huaneng")
public class ImageFileDownloadController {

    @Resource
    protected CommonSftpComponent commonSftpComponent;

    @Resource(name = "fileUploadExecutor")
    protected ThreadPoolTaskExecutor fileUploadExecutor;

    @Resource
    private ImageFileDownloadService imageFileDownloadService;

    public static Logger logger = LoggerFactory.getLogger(ImageFileDownloadController.class);

    /**
     * 参数示例：
     * {"tenantId":"morse_dev_demo","queryStartId":0,"queryNum":1000,"batchNum":200,"handleNum":1000}
     * {
     *     "tenantId": "morse_dev_demo",
     *     "queryStartId": 0,
     *     "queryNum": 1000,
     *     "batchNum": 200,
     *     "handleNum": 1000
     * }
     */
    /**
     * @Description：华能下载文件并且上传文件到SFTP
     * @Author： ext.fengcheng
     * @Date：2023/9/19 9:55
     * @tenantId, 租户id
     * @queryStartId, 查询开始ID，从哪个ID开始查询，默认为：从0开始
     * @queryNum, 每次查询多少条数据，不传则默认为1千条
     * @batchNum, 根据每次查询的数据，分批处理数据，默认为2百条
     * @handleNum 每次多少数据进行一次文件上传，默认为1千条
     * @Return： boolean
     */
    @PostMapping("/downloadFilesAndUploadFilesToSftp")
    public Boolean downloadFilesAndUploadFilesToSftp(@RequestBody ImageFileDownloadAndUploadReqDto reqDto) {
        logger.info("downloadFilesAndUploadFilesToSftp.华能影像件下载及上传文件到SFTP,开始时间：{}", DateUtils.toString(new Date()));
        if (ObjectUtils.isEmpty(reqDto)) {
            logger.error("参数校验为空！");
            return false;
        }
        String tenantId = reqDto.getTenantId();             // 租户id
        Long queryStartId = reqDto.getQueryStartId();       // 查询开始ID，从哪个ID开始查询，默认为：从0开始
        Long queryNum = reqDto.getQueryNum();               // 每次查询多少条数据，不传则默认为1千条
        Long batchNum = reqDto.getBatchNum();               // 根据每次查询的数据，分批处理数据，默认为2百条
        Boolean isTest = reqDto.getIsTest();                // 是否进行测试
        if (StringUtils.isAnyBlank(tenantId)) {
            logger.error("必填参数为空，reqDto：{}", JSONObject.toJSONString(reqDto));
            return false;
        }
        try {
            // 开始导出文件数据，处理过程中，发生异常则直接结束
            boolean result = imageFileDownloadService.downloadFilesAndUploadFilesToSftp(tenantId, queryStartId, queryNum, batchNum, isTest);
            if (!result) {
                logger.info("华能影像件下载及上传文件到SFTP，处理失败！");
                return false;
            }
            logger.info("华能影像件下载及上传文件到SFTP，处理结束，完成时间：{}", DateUtils.toString(new Date()));
            return true;
        } catch (Exception e) {
            logger.error("华能影像件下载及上传文件到SFTP过程中发生异常，异常信息：{}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 参数示例：
     {
     "remotePath": "/upload/morse/MCLIOU21080972302471911106040000/",
     "remoteFileName": "金条借款《金条借款合同》.pdf",
     "localPath": "/export/server/file/",
     "localFileName": "jt_loan_MCLIOU21080972302471911106040000.pdf"
     }
     */
    /**
     * @Description：从SFTP下载文件到本地
     * @Author： ext.fengcheng
     * @Date：2023/9/27 16:47
     * @remotePath： SFTP文件目录
     * @remoteFileName： SFTP文件目录下的文件名
     * @localPath： 本地文件目录
     * @localFileName： 本地文件目录下存放文件名
     * @Return： boolean
     */
    @PostMapping("/downloadFileToSftp")
    public Boolean downloadFileToSftp(@RequestBody ImageFileDownloadAndUploadReqDto reqDto) {
        logger.info("downloadFileToSftp.从SFTP下载文件到本地,reqDto：{}|开始时间：{}", JSONObject.toJSONString(reqDto), DateUtils.toString(new Date()));
        if (ObjectUtils.isEmpty(reqDto)) {
            logger.error("参数校验为空！");
            return false;
        }
        try {
            // 开始导出文件数据，处理过程中，发生异常则直接结束
            boolean result = imageFileDownloadService.downloadFileToSftp(reqDto.getRemotePath(), reqDto.getRemoteFileName(),
                    reqDto.getLocalPath(), reqDto.getLocalFileName(), reqDto.getIsBatchDownload());
            if (!result) {
                logger.info("从SFTP下载文件到本地，处理失败！");
                return false;
            }
            logger.info("从SFTP下载文件到本地，处理结束，完成时间：{}", DateUtils.toString(new Date()));
            return true;
        } catch (Exception e) {
            logger.error("从SFTP下载文件到本地过程中发生异常，异常信息：{}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description：统计上传文件总数
     * @Author： ext.fengcheng
     * @Date：2023/10/16 14:20
     * @Param： []
     * @Return： java.lang.Boolean
     */
    @PostMapping("/countUploadsFileTotal")
    public Boolean countUploadsFileTotal() {
        System.out.println("countUploadsFileTotal.统计上传文件总数,开始时间：【" + DateUtils.toString(new Date()) + "】");
        Integer fileTotal = imageFileDownloadService.countUploadsFileTotal();
        System.out.println("countUploadsFileTotal.已上传文件总数为：【" + fileTotal + "】.处理完成,结束时间：【" + DateUtils.toString(new Date()) + "】");
        return true;
    }

    @PostMapping("/clearLocalCache")
    public Boolean clearLocalCache() {
        logger.error("clearLocalCache.清除本地缓存【localQueue】,开始时间：{}", DateUtils.toString(new Date()));
        imageFileDownloadService.clearLocalCache();
        logger.error("clearLocalCache.清除本地缓存【localQueue】,完成时间：{}", DateUtils.toString(new Date()));
        return true;
    }

    /**
     * @Description：
     * @Param：reqDto
     * @Author： fengcheng
     * @Date： 2024/10/9 10:08
     * @Return： java.lang.Boolean
     */
    @PostMapping("/testMultithreading")
    public Boolean testMultithreading(@RequestBody ImageFileDownloadAndUploadReqDto reqDto) {
        System.out.println("downloadFilesAndUploadFilesToSftp.从SFTP下载文件到本地,开始时间：【" + DateUtils.toString(new Date()) + "】");
        Map<String, Integer> fileBufferMap = new HashMap<>();
        int index = 1;
        for (int i = 0; i < 100; i++) {
            fileBufferMap.put("test_" + i, i);
            if (fileBufferMap.size() == 20) {
                SftpUtil sftp = commonSftpComponent.initSftpConnection();
                Map<String, Integer> fileBufferMapBatch = new HashMap<>(fileBufferMap);
                System.out.println("==========================>集合已存满20个，处理第【" + index + "】");
                fileUploadExecutor.submit(() -> {
                    System.out.println("打开链接");
                    uploadFileToSftp(fileBufferMapBatch);
                    System.out.println("关闭连接");
                });
                fileBufferMap.clear();
                sftp.disconnect();
                index++;
            }
        }
        System.out.println("处理完成,结束时间：【" + DateUtils.toString(new Date()) + "】");
        return true;
    }

    public void uploadFileToSftp(Map<String, Integer> fileBufferMap) {
        System.out.println("uploadFileToSftp.上传文件到华能SFTP服务器,开始处理,长度【" + fileBufferMap.size() + "】");
        fileBufferMap.forEach((key, value) -> {
            try {
                System.out.println("开始睡眠1秒钟");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        System.out.println("uploadFileToSftp.上传文件到华能SFTP服务器，处理结束");
    }
}
